﻿using System;
using System.Data.SqlClient;
using System.IO;
using System.Windows.Forms;
using ConfigDatabase.Properties;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;

namespace ConfigDatabase
{
    public partial class FormConfig : Form
    {
        private readonly SqlConnectionString _connectionString;

        private readonly string _connectionStringFile;
        private readonly string _installDir;
        private readonly string _queryFile;

        public FormConfig()
        {
            InitializeComponent();
            _connectionString = new SqlConnectionString();

            _installDir = Application.StartupPath;
            _connectionStringFile = Path.Combine(_installDir, "ConnectionString.txt");
            _queryFile = Path.Combine(_installDir, "SqlScript.sql");

            LoadConnectFromFile();
        }

        public FormConfig(string installDir)
        {
            InitializeComponent();
            _connectionString = new SqlConnectionString();

            _installDir = installDir;
            _connectionStringFile = Path.Combine(_installDir, "Credit Education.exe.config");
            _queryFile = Path.Combine(_installDir, "SqlScript.sql");

            LoadConnectFromFile();
        }

        private void LoadConnectFromFile()
        {
            if (File.Exists(_connectionStringFile))
            {
                string connectionString = File.ReadAllText(_connectionStringFile);
                connectionString = GetConnectionString(connectionString);

                if (!string.IsNullOrEmpty(connectionString))
                {
                    txtConnectString.Text = connectionString;
                }
            }
            else
            {
                txtConnectString.Text = "File config no found: " + _connectionStringFile;
            }

            if (File.Exists(_queryFile))
            {
                txtPathScript.Text = _queryFile;
            }
        }

        private string GetConnectionString(string connectionString)
        {
            int start = connectionString.IndexOf("&quot;") + "&quot;".Length;
            int end = connectionString.IndexOf("&quot;", start + 1);
            connectionString = connectionString.Substring(start, end - start);
            return connectionString;
        }

        private void TxtConnectString_TextChanged(object sender, EventArgs e)
        {
            _connectionString.ConnectionString = txtConnectString.Text;
            txtServerName.Text = _connectionString.Server;
            txtDatabaseName.Text = _connectionString.Database;
            txtServerUsername.Text = _connectionString.UserId;
            txtServerPassword.Text = _connectionString.Password;

            lblError.Visible = _connectionString.ValidateConnectionString(txtConnectString.Text);
        }

        private void TxtServerName_TextChanged(object sender, EventArgs e)
        {
            _connectionString.Server = txtServerName.Text;
            txtConnectString.Text = _connectionString.ConnectionString;
        }

        private void TxtDatabaseName_TextChanged(object sender, EventArgs e)
        {
            _connectionString.Database = txtDatabaseName.Text;
            txtConnectString.Text = _connectionString.ConnectionString;
        }

        private void TxtServerUsername_TextChanged(object sender, EventArgs e)
        {
            _connectionString.UserId = txtServerUsername.Text;
            txtConnectString.Text = _connectionString.ConnectionString;
        }

        private void TxtServerPassword_TextChanged(object sender, EventArgs e)
        {
            _connectionString.Password = txtServerPassword.Text;
            txtConnectString.Text = _connectionString.ConnectionString;
        }

        private void BtnTest_Click(object sender, EventArgs e)
        {
            var connectionString = (SqlConnectionString)_connectionString.Clone();
            connectionString.Database = string.Empty;

            var connection = new SqlConnection(connectionString.ConnectionString);
            try
            {
                connection.Open();
                connection.Close();
                MessageBox.Show(Resources.DoSuccess);
            }
            catch (Exception ex)
            {
                connection.Dispose();
                MessageBox.Show(ex.Message);
                txtError.Text = ex.Message;
            }
        }

        private void BtnBrowse_Click(object sender, EventArgs e)
        {
            var dialog = new OpenFileDialog { Filter = Resources.SqlFileFilter };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                txtPathScript.Text = dialog.FileName;
            }
        }

        private void BtnGenerateDb_Click(object sender, EventArgs e)
        {
            if (chkCreateNewDb.Checked)
            {
                CreateNewDatabase();
            }
            RunScript();
        }

        private void RunScript()
        {
            try
            {
                string content = @"<?xml version=~1.0~ encoding=~utf-8~ ?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy=~true~>
    <supportedRuntime version=~v4.0~/>
    <requiredRuntime version=~v4.0.20506~/>
  </startup>
</configuration>";
                File.WriteAllText(Application.ExecutablePath + ".Config", content.Replace("~", "\""));

                var connectionString = (SqlConnectionString)_connectionString.Clone();
                connectionString.Database = string.Empty;

                string script = File.ReadAllText(txtPathScript.Text);
                var conn = new SqlConnection(connectionString.ConnectionString);
                var server = new Server(new ServerConnection(conn));
                server.ConnectionContext.ExecuteNonQuery(script);

                MessageBox.Show(Resources.DoSuccess);
            }
            catch (Exception ex)
            {
                txtError.Text = ex.Message;
                MessageBox.Show(ex.Message);
            }
        }

        private void CreateNewDatabase()
        {
            var connectionString = (SqlConnectionString)_connectionString.Clone();
            connectionString.Database = "master";

            var connection = new SqlConnection(connectionString.ConnectionString);
            string query =
                string.Format("if not exists(select * from sys.databases where name = '{0}') CREATE DATABASE {0}",
                              _connectionString.Database);
            var command = new SqlCommand(query, connection);
            try
            {
                connection.Open();
                command.ExecuteNonQuery();
                connection.Close();
                MessageBox.Show(Resources.DoSuccess);
            }
            catch (Exception ex)
            {
                connection.Dispose();
                txtError.Text = ex.Message;
                MessageBox.Show(ex.Message);
            }
        }

        private void Close_Click(object sender, EventArgs e)
        {
            Dispose();
        }

        private void BtnSave_Click(object sender, EventArgs e)
        {
            string configData = File.ReadAllText(_connectionStringFile);

            string connectionString = GetConnectionString(configData);

            configData = configData.Replace(connectionString, _connectionString.ConnectionString);
            File.WriteAllText(_connectionStringFile, configData);
        }
    }
}